package com.spsoft.vatoutinv.service.vmsenterpriseinforisk.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spsoft.core.enums.ResponseEnum;
import com.spsoft.core.exception.BusinessException;
import com.spsoft.core.model.Result;
import com.spsoft.core.model.bo.TokenUser;
import com.spsoft.core.model.leqidmz.param.BaseNsrRequestParams;
import com.spsoft.core.model.leqidmz.response.QueryEnterpriseInfoRiskVO;
import com.spsoft.core.utils.BeanUtils;
import com.spsoft.einvoicetodmz.service.DmzApiClientService;
import com.spsoft.vatoutinv.constants.CommonConstant;
import com.spsoft.vatoutinv.entity.vmsenterpriseinfo.VmsEnterpriseInfo;
import com.spsoft.vatoutinv.entity.vmsenterpriseinforisk.VmsEnterpriseInfoRisk;
import com.spsoft.vatoutinv.entity.vmsenterpriseinforisk.VmsEnterpriseInfoRiskLog;
import com.spsoft.vatoutinv.enums.CommonEnum;
import com.spsoft.vatoutinv.mapper.VmsEnterpriseInfoRiskLogMapper;
import com.spsoft.vatoutinv.mapper.VmsEnterpriseInfoRiskMapper;
import com.spsoft.vatoutinv.model.dto.vmsenterpriseinforisk.VmsEnterpriseInfoRiskDto;
import com.spsoft.vatoutinv.model.vo.vmsenterpriseinforisk.VmsEnterpriseInfoRiskVo;
import com.spsoft.vatoutinv.service.vmsenterpriseinforisk.VmsEnterpriseInfoRiskService;
import com.spsoft.vms.redis.RedisService;
import com.spsoft.vms.redis.constant.RedisConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 纳税人风险信息 服务实现类
 * </p>
 *
 * @author chenxudong
 * @since 2023-11-22
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VmsEnterpriseInfoRiskServiceImpl extends ServiceImpl<VmsEnterpriseInfoRiskMapper, VmsEnterpriseInfoRisk> implements VmsEnterpriseInfoRiskService {

    public static final String LOG_MSG = "(纳税人风险信息实现层)";

    private final RedisService redisService;

    private final DmzApiClientService dmzApiClientService;

    private final VmsEnterpriseInfoRiskMapper vmsEnterpriseInfoRiskMapper;

    private final VmsEnterpriseInfoRiskLogMapper vmsEnterpriseInfoRiskLogMapper;

    @Override
    public Result<VmsEnterpriseInfoRiskVo> queryVmsEnterpriseInfoRisk(VmsEnterpriseInfoRiskDto vmsEnterpriseInfoRiskDto) {
        // 查询数据库获取纳税人风险信息
        LambdaQueryWrapper<VmsEnterpriseInfoRisk> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VmsEnterpriseInfoRisk::getDeptCode, vmsEnterpriseInfoRiskDto.getDeptCode());
        VmsEnterpriseInfoRisk vmsEnterpriseInfoRisk = vmsEnterpriseInfoRiskMapper.selectOne(queryWrapper);

        // 将数据库返回数据转换为VO返回前端
        VmsEnterpriseInfoRiskVo vmsEnterpriseInfoRiskVo = new VmsEnterpriseInfoRiskVo();
        if (vmsEnterpriseInfoRisk != null) {
            BeanUtils.copyBeanProp(vmsEnterpriseInfoRiskVo, vmsEnterpriseInfoRisk);
        }

        return Result.OK(vmsEnterpriseInfoRiskVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> getVmsEnterpriseInfoRiskByLq(VmsEnterpriseInfoRiskDto vmsEnterpriseInfoRiskDto, TokenUser userInfo) {
        // 调用乐企接口获取纳税人风险信息
        BaseNsrRequestParams params = new BaseNsrRequestParams();
        params.setNsrsbh(vmsEnterpriseInfoRiskDto.getNsrsbh());
        params.setCreateUser(userInfo.getUserCode());
        params.setDeptCode(userInfo.getDeptCode());
        Result<QueryEnterpriseInfoRiskVO> result = dmzApiClientService.queryEnterpriseRisk(params, null);

        // 先记录日志操作
        VmsEnterpriseInfoRiskLog vmsEnterpriseInfoRiskLog = new VmsEnterpriseInfoRiskLog();
        vmsEnterpriseInfoRiskLog.setDeptCode(userInfo.getDeptCode());
        vmsEnterpriseInfoRiskLog.setNsrsbh(vmsEnterpriseInfoRiskDto.getNsrsbh());
        vmsEnterpriseInfoRiskLog.setCreateTime(new Date());
        vmsEnterpriseInfoRiskLog.setCreateUser(userInfo.getUserCode());
        vmsEnterpriseInfoRiskLog.setCreateUsername(userInfo.getUserName());

        if (ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            log.info("{}调用DMZ查询纳税人风险信息成功", LOG_MSG);
            QueryEnterpriseInfoRiskVO data = result.getData();
            vmsEnterpriseInfoRiskLog.setOperateStatus(CommonConstant.STR_01);
            vmsEnterpriseInfoRiskLog.setOperateMsg(JSONObject.toJSONString(data));
            vmsEnterpriseInfoRiskLog.setFxnsrlx(StringUtils.isBlank(data.getFxnsrlx()) ? CommonConstant.STR_00 : data.getFxnsrlx());
            vmsEnterpriseInfoRiskLog.setNsryjjb(StringUtils.isBlank(data.getNsryjjb()) ? CommonConstant.STR_00 : data.getNsryjjb());
            vmsEnterpriseInfoRiskLog.setNsrxydj(data.getNsrxydj());
            vmsEnterpriseInfoRiskLog.setFxnsrbz(data.getFxnsrbz());
            vmsEnterpriseInfoRiskLogMapper.insert(vmsEnterpriseInfoRiskLog);

            // 查询数据库是否有记录，无则新增，有则更新
            LambdaQueryWrapper<VmsEnterpriseInfoRisk> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(VmsEnterpriseInfoRisk::getDeptCode, userInfo.getDeptCode());
            VmsEnterpriseInfoRisk riskInfo = vmsEnterpriseInfoRiskMapper.selectOne(queryWrapper);

            VmsEnterpriseInfoRisk vmsEnterpriseInfoRisk = new VmsEnterpriseInfoRisk();
            // Bean转换
            BeanUtils.copyBeanProp(vmsEnterpriseInfoRisk, data);
            vmsEnterpriseInfoRisk.setLogId(vmsEnterpriseInfoRiskLog.getId());
            vmsEnterpriseInfoRisk.setDeptCode(userInfo.getDeptCode());
            vmsEnterpriseInfoRisk.setNsrsbh(vmsEnterpriseInfoRiskDto.getNsrsbh());
            vmsEnterpriseInfoRisk.setFxnsrlx(StringUtils.isBlank(data.getFxnsrlx()) ? CommonConstant.STR_00 : data.getFxnsrlx());
            vmsEnterpriseInfoRisk.setNsryjjb(StringUtils.isBlank(data.getNsryjjb()) ? CommonConstant.STR_00 : data.getNsryjjb());
            vmsEnterpriseInfoRisk.setUpdateTime(new Date());
            vmsEnterpriseInfoRisk.setUpdateUser(userInfo.getUserCode());
            vmsEnterpriseInfoRisk.setUpdateUsername(userInfo.getUserName());
            if (riskInfo != null && riskInfo.getId() != 0) {
                vmsEnterpriseInfoRisk.setId(riskInfo.getId());
                this.updateById(vmsEnterpriseInfoRisk);
            } else {
                vmsEnterpriseInfoRisk.setCreateTime(new Date());
                vmsEnterpriseInfoRisk.setCreateUser(userInfo.getUserCode());
                vmsEnterpriseInfoRisk.setCreateUsername(userInfo.getUserName());
                this.save(vmsEnterpriseInfoRisk);
            }
            // 刷新redis缓存
            String redisKey = String.format(RedisConstant.REDIS_VMSENTERPRISE_RISKINFO_CACHE_KEY, params.getDeptCode());
            redisService.setCacheObject(redisKey, JSONObject.toJSONString(vmsEnterpriseInfoRisk), RedisConstant.REDIS_EXPIRE_TIME_6H, TimeUnit.SECONDS);
        } else {
            log.error("{}调用DMZ查询纳税人风险信息失败，原因：{}", LOG_MSG, result.getMessage());
            vmsEnterpriseInfoRiskLog.setOperateStatus(CommonConstant.STR_02);
            vmsEnterpriseInfoRiskLog.setOperateMsg(result.getMessage());
            vmsEnterpriseInfoRiskLogMapper.insert(vmsEnterpriseInfoRiskLog);
            return Result.ERROR(result.getCode(), result.getMessage());
        }
        return Result.OK_MSG(ResponseEnum.LEQI_SUCCESS.getMsg());
    }

    @Override
    public VmsEnterpriseInfoRisk getRiskInfoByRedis(String deptCode) {
        String redisKey = String.format(RedisConstant.REDIS_VMSENTERPRISE_RISKINFO_CACHE_KEY, deptCode);
        String redisValue = redisService.getCacheObject(redisKey);
        if (StringUtils.isBlank(redisValue)) {
            LambdaQueryWrapper<VmsEnterpriseInfoRisk> query = new LambdaQueryWrapper<>();
            query.eq(VmsEnterpriseInfoRisk::getDeptCode, deptCode);
            VmsEnterpriseInfoRisk vmsEnterpriseInfoRisk = this.getOne(query);
            if (vmsEnterpriseInfoRisk != null) {
                redisValue = JSONObject.toJSONString(vmsEnterpriseInfoRisk);
                redisService.setCacheObject(redisKey, redisValue, RedisConstant.REDIS_EXPIRE_TIME_6H, TimeUnit.SECONDS);
            } else {
                return null;
            }
        }
        return JSONObject.parseObject(redisValue, VmsEnterpriseInfoRisk.class);
    }

    /**
     * 校验 风险类型 和 预警级别
     */
    @Override
    public void checkStatus(String deptCode, String type) {
        VmsEnterpriseInfoRisk risk = getRiskInfoByRedis(deptCode);
        if (risk != null) {
            // 风险纳税人类型
            if (CommonEnum.RISK_TYPE_01.getKey().equals(risk.getFxnsrlx())) {
                if ("1".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_01);
                }
                if ("2".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_02);
                }
                if ("3".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_03);
                }
                if ("4".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_11);
                }
            }
            // 纳税人预警级别
            if (CommonEnum.RISK_WARNING_LEVEL_01.getKey().equals(risk.getNsryjjb())) {
                if ("1".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_04);
                }
                if ("2".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_05);
                }
                if ("3".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_06);
                }
                if ("4".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_12);
                }
            }
            // 风险纳税人标志
            if (CommonEnum.RISK_FLAG_Y.getKey().equals(risk.getFxnsrbz())) {
                if ("1".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_07);
                }
                if ("2".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_08);
                }
                if ("3".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_09);
                }
                if ("4".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_13);
                }
            }
        } else {
            throw new BusinessException(ResponseEnum.ENTERPRISE_RISK_ERROR_10);
        }
    }

}
